<?php
/**
 *  如果m满足了filter，则不处理
 */

function array_batch($array, $func, $withKey = FALSE, $filter = NULL) {
	//var_dump($filter);
	$_ret = array();
	foreach ($array as $v) {
		if ($filter == NULL || !preg_match($filter, $v)) {
			if ($withKey) {
				if (is_array($func) && (is_object($func[0]) || class_exists($func[0]))) {
					$_ret[$v] = call_user_func(array(
						$func[0],
						$func[1]
					) , $v);
				}
				else {
					$_ret[$v] = call_user_func($func, $v);
				}
			}
			else {
				if (is_array($func) && (is_object($func[0]) || class_exists($func[0]))) {
					$_ret[] = call_user_func(array(
						$func[0],
						$func[1]
					) , $v);
				}
				else {
					$_ret[] = call_user_func($func, $v);
				}
			}
		}
		else {
			$_ret[] = $v;
		}
	}
	return $_ret;
}
/**
 * array_compression();
 * 剔除数组中的空白元素
 * @param array
 * @return array
 */

function array_compression($array) {
	if (!is_array($array)) return FALSE;
	$ret = array();
	//$is_index=is_index_array($array);
	foreach ($array as $k => $v) {
		if (trim(preg_replace("/\s/", '', $v)) !== '') {
			$ret[$k] = $v;
		}
	}
	return $ret;
}
/**
 *  p判断数组是否为索引数组，还是字典数组
 */

function is_index_array($mixed) {
	if (is_array($mixed) && !empty($mixed) && isset($mixed[0])) {
		return TRUE;
	}
	return FALSE;
}

function hmac_sha1($key, $data) {
	if (function_exists('hash_hmac')) {
		return hash_hmac('sha1', $data, $key);
	}
	else {
		$blocksize = 64;
		$hashfunc = 'sha1';
		if (strlen($key) > $blocksize) $key = pack('H*', $hashfunc($key));
		$key = str_pad($key, $blocksize, chr(0x00));
		$ipad = str_repeat(chr(0x36) , $blocksize);
		$opad = str_repeat(chr(0x5c) , $blocksize);
		$hmac = pack('H*', $hashfunc(($key ^ $opad) . pack('H*', $hashfunc(($key ^ $ipad) . $data))));
		return bin2hex($hmac);
	}
}

function array_string($array, $sepKeyVal = '=', $sepPart = '&') {
	$ret = array();
	foreach ($array as $k => $v) {
		$ret[] = $k . $sepKeyVal . $v;
	}
	return join($sepPart, $ret);
}
if (!function_exists('hash_hmac')) {
	
	function hash_hmac($algo, $data, $key) {
		$blocksize = 64;
		if (strlen($key) > $blocksize) $key = pack('H*', $hashfunc($key));
		$key = str_pad($key, $blocksize, chr(0x00));
		$ipad = str_repeat(chr(0x36) , $blocksize);
		$opad = str_repeat(chr(0x5c) , $blocksize);
		$hmac = pack('H*', $algo(($key ^ $opad) . pack('H*', $algo(($key ^ $ipad) . $data))));
		return bin2hex($hmac);
	}
}

function urlencode_rfc3986($input) {
	if (is_array($input)) {
		return array_map(array(
			'OAuthUtil',
			'urlencode_rfc3986'
		) , $input);
	}
	else if (is_scalar($input)) {
		return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($input)));
	}
	else {
		return '';
	}
}

function getClientIPAddr() {
	if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
		$ip = $_SERVER['HTTP_CLIENT_IP'];
	}
	elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
		$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
	}
	else {
		$ip = $_SERVER['REMOTE_ADDR'];
	}
	return $ip;
}
///获取变量的名字

function getVarName($var) {
	$trace = debug_backtrace();
	$vLine = file($trace[0]['file']);
	$fLine = $vLine[$trace[0]['line'] - 1];
	//var_dump($fLine);
	preg_match("#\\$(\w+)#", $fLine, $match);
	return $match[1];
}

function argCheck($arg, $filter) {
	///类似于这样的结构
	$filter = "empty|!isemail|isNull|bigger('10')|indexOf('[a|b|c]')";
	$argName = getVarName($arg);
}
///带有2个下划线结束的方法为引用型改造方法

function trim__(&$string) {
	$string = trim($string);
	return $string;
}
/**
 *  存在则返回，不存在返回null
 */

function CK($arr, $k, $exception = NULL) {
	if (isset($arr[$k])) {
		return $arr[$k];
	}
	elseif (is_string($exception)) {
		throw new Exception($exception);
	}
	return NULL;
}
/**
 *  获取数组的部分内容
 */

function array_gets($needle, $haystack, $withKey = FALSE) {
	if (is_array($haystack) && is_array($needle)) {
		$ret = array();
		$ks = array_keys($haystack);
		foreach ($needle as $key) {
			if (in_array($key, $ks)) {
				if ($withKey) $ret[$key] = $haystack[$key];
				else $ret[] = $haystack[$key];
			}
		}
		return $ret;
	}
	return NULL;
}
/**
 *  获取路径的文件名称
 */

function filename($path, $withSuffix = FALSE) {
	$name = basename($path);
	if (!$withSuffix) list($name, $suffix) = explode('.', $name);
	return $name;
}
/**
 *  根据绝对地址获取相对地址或者web地址
 */

function getWebURL($path, $fullPath = FALSE) {
	$root = __ROOT__;
	//var_dump($root,$path);
	$pos = strlen($root);
	$path = substr($path, $pos);
	//var_dump($_SERVER);
	if ($fullPath) return __BASE_URI__ . $path;
	else return $path;
}
//****************************************************************************

//			数组扩展函数集

//****************************************************************************

/**
  *  array_search扩展
  *  $v,array(array('id'=>'','xx'=>$v))
  *  在一个恶二维关联数组中查找某个数据段是否存在，类似sql的select where
  *  $where=array('a=x&&b>x||c<xx'); in is not support
  */
function array_select($haystack,$where){
	$checked='$checked=';
	if(!isset($haystack[0])) return FALSE;
	else{
		$token=$haystack[0];
		foreach($token as $k=>$v){
			$where=strstr($where,$k,'$'.$k);
		}
	}
	//$wh
	foreach($haystack as $k=>$v){
		$$k=$v;
		
		//strtr($where,$k)
		//eval($where);
	}
}

///二维数组根on据进行排序

function array_sort($array, $on, $order = SORT_ASC) {
	$new_array = array();
	$sortable_array = array();
	if (count($array) > 0) {
		foreach ($array as $k => $v) {
			if (is_array($v)) {
				foreach ($v as $k2 => $v2) {
					if ($k2 == $on) {
						$sortable_array[$k] = $v2;
					}
				}
			}
			else {
				$sortable_array[$k] = $v;
			}
		}
		switch ($order) {
			case SORT_ASC:
				asort($sortable_array);
			break;
			case SORT_DESC:
				arsort($sortable_array);
			break;
		}
		foreach ($sortable_array as $k => $v) {
			$new_array[$k] = $array[$k];
		}
	}
	return $new_array;
}
/*
 * function warp
 * @param $warped,$str
*/

function warp($warped, $mixed) {
	if (!is_array($mixed)) {
		return "{$warped}{$mixed}{$warped}";
	}
	else {
		$ret = array();
		foreach ($mixed as $str) {
			$ret[] = warp($warped, $str);
		}
		return $ret;
	}
}
/**
 *  检查元素是否可以通过数组中每个正则表达式或者通配符的匹配
 *  $arr=array("/^xxxxx$/","...");
 *
 */

function is_match_array($str, $arr) {
	foreach ($arr as $preg) {
		if (!is_preg($preg)) {
			if (wildcard_match($preg, $str)) return TRUE;
		}
		else {
			if (preg_match($preg, $str)) return TRUE;
		}
	}
	return FALSE;
}
/**
 *  p判断一个字符串是否是正则表达式
 */

function is_preg($str) {
	return substr($str, 0, 1) === '/' && substr($str, strlen($str) - 1) === '/';
}
/**
 *  通配符匹配
 *  暂时支持*和?通配
 */

function wildcard_match($wildcard, $str, &$matches = array()) {
	$wildcard = strtr($wildcard, array(
		'*' => '(\w)*',
		'?' => '(\w)?',
		'.' => '\.',
		'/' => '\/',
		'-' => '\-'
	));
	//var_dump($wildcard,$str);
	return preg_match("/^" . $wildcard . "$/", $str, $matches);
}
/**
 *  获取客户端IP地址
 */

function get_client_ip() {
	static $ip = NULL;
	if ($ip == NULL) {
		$unkown = 'unknow';
		foreach (array(
			'HTTP_CLIENT_IP',
			'HTTP_X_FORWARDED_FOR',
			'HTTP_X_FORWARDED',
			'HTTP_X_CLUSTER_CLIENT_IP',
			'HTTP_FORWARDED_FOR',
			'HTTP_FORWARDED',
			'REMOTE_ADDR'
		) as $key) {
			if (isset($_SERVER[$key])) {
				$ip = $_SERVER[$key];
				if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
					$ip = $unkown;
				}
				break;
			}
		}
		$ip = $unkown;
	}
	return $ip;
}

function check_session_bind_ip() {
	$sid = session_id();
	$cache = APP::ADP('cache');
	$ip = get_client_ip(IP_LONG);
	if ($cip = $cache->get('SESSION_' . $sid)) {
		$cache->set('SESSION_' . $sid, $ip);
		return TRUE;
	}
	else {
		if ($cip == $ip) {
			return TRUE;
		}
	}
	return FALSE;
}
/**
 *  csrf x需要支持js以及手动url处理
 *  解决一个页面中多个相同URL请求问题
 *  多次刷新原始页面，会形成session垃圾
 */

function url_csrf_push($url) {
	if (!isset($_SESSION['CSRF_STACK'])) {
		$_SESSION['CSRF_STACK'] = array();
	}
	$CSRF_STACK = & $_SESSION['CSRF_STACK'];
	///query key is gen as well
	$key = V('o:SYS/CSRF_KEY');
	$val = uniqid();
	$url_key = md5($url);
	if (!isset($CSRF_STACK[$url_key])) {
		$CSRF_STACK[$url_key] = array();
	}
	$CSRF_STACK[$url_key][] = $val;
	return url_add_query($url, array(
		$key => $val
	));
}

function url_csrf_pop($index, $url = NULL) {
	if ($url == NULL) {
		$url = V('s:REQUEST_URI');
	}
	$CSRF_STACK = & $_SESSION['CSRF_STACK'];
	$key = V('o:SYS/CSRF_KEY');
	$durl = url_del_query($url, $key);
	$url_key = md5($durl);
	$arr = $CSRF_STACK[$url_key];
	unset($CSRF_STACK[$url_key][$index]);
	return TRUE;
}

function url_csrf_check(&$index, $url = NULL) {
	if ($url == NULL) {
		$url = V('s:REQUEST_URI');
	}
	$CSRF_STACK = & $_SESSION['CSRF_STACK'];
	$key = V('o:SYS/CSRF_KEY');
	$durl = url_del_query($url, $key);
	$url_key = md5($durl);
	if (isset($CSRF_STACK[$url_key])) {
		$val = $CSRF_STACK[$url_key];
		$url_val = url_get_query_by_key($url, $key);
		if (in_array($url_val, $val)) {
			$index = array_search($url_val, $val);
			return TRUE;
		}
		return FALSE;
	}
	return FALSE;
}

function url_del_query($url, $key) {
	$arr = url_get_query_array($url);
	//var_dump($arr);
	arrary_del($arr, $key);
	//var_dump($url);
	$require = url_get_require($url);
	return url_add_query($require, $arr);
}

function url_get_query_array($url) {
	$ret = array();
	$arr = explode('?', $url);
	if (count($arr) == 2) {
		$query = $arr[1];
		$qarr = explode('&', $query);
		foreach ($qarr as $qur) {
			$kv = explode('=', $qur);
			if (count($kv) == 2) {
				$ret[$kv[0]] = $kv[1];
			}
		}
		return $ret;
	}
	else {
		return array();
	}
}
/**
 *  fetch only the require from the url
 */

function url_get_require($url) {
	$pos = strpos($url, '?');
	return substr($url, 0, $pos);
}

function url_get_query_by_key($url, $key) {
	$arr = url_get_query_array($url);
	//var_dump($arr);
	return $arr[$key];
}
/**
 *  $query is
 */

function url_add_query($url, $query) {
	if (is_array($query)) {
		$query = indexArray2str($query);
	}
	if ($query == '') return $url;
	$url = rtrim($url, '?');
	//var_dump($url);
	if (strpos($url, '?')) {
		return $url . '&' . $query;
	}
	else {
		return $url . '?' . $query;
	}
}
/**
 *  索引数组字符串组合
 */

function indexArray2str($array, $s1 = '&', $s2 = '=') {
	$ret = '';
	foreach ($array as $i => $v) {
		$ss = $ret == '' ? '' : $s1;
		$ret.= $ss . $i . $s2 . $v;
	}
	return $ret;
}

function arrary_del(&$array, $key) {
	$ret = array();
	foreach ($array as $i => $v) {
		if ($key != $i) $ret[$i] = $v;
	}
	return $array = $ret;
}
/**
 *  s私有key申明 j兼容php4
 */

function privete_key($key) {
	if ($key && substr($key, 0, 1) === '_') {
		return TRUE;
	}
	return FALSE;
}
/**
 *  判断一个数据是否是用户输入
 *  '0'为输入
 */

function is_user_input($val) {
	return empty($val) && $val !== '0';
}
/**
 *  #&xxxx 转换为utf8
 */

function unicode2utf8($input, $array = TRUE) {
	$utf = '';
	if (!is_array($input)) {
		$input = str_replace('&#', '', $input);
		$input = explode(';', $input);
		$len = count($input);
		unset($input[$len - 1]);
	}
	for ($i = 0;$i < count($input);$i++) {
		if ($input[$i] < 128) {
			$byte1 = $input[$i];
			$utf.= chr($byte1);
		}
		if ($input[$i] >= 128 && $input[$i] <= 2047) {
			$byte1 = 192 + (int)($input[$i] / 64);
			$byte2 = 128 + ($input[$i] % 64);
			$utf.= chr($byte1) . chr($byte2);
		}
		if ($input[$i] >= 2048 && $input[$i] <= 65535) {
			$byte1 = 224 + (int)($input[$i] / 4096);
			$byte2 = 128 + ((int)($input[$i] / 64) % 64);
			$byte3 = 128 + ($input[$i] % 64);
			$utf.= chr($byte1) . chr($byte2) . chr($byte3);
		}
		if ($input[$i] >= 65536 && $input[$i] <= 2097151) {
			$byte1 = 240 + (int)($input[$i] / 262144);
			$byte2 = 128 + ((int)($input[$i] / 4096) % 64);
			$byte3 = 128 + ((int)($input[$i] / 64) % 64);
			$byte4 = 128 + ($input[$i] % 64);
			$utf.= chr($byte1) . chr($byte2) . chr($byte3) . chr($byte4);
		}
		if ($input[$i] >= 2097152 && $input[$i] <= 67108863) {
			$byte1 = 248 + (int)($input[$i] / 16777216);
			$byte2 = 128 + ((int)($input[$i] / 262144) % 64);
			$byte3 = 128 + ((int)($input[$i] / 4096) % 64);
			$byte4 = 128 + ((int)($input[$i] / 64) % 64);
			$byte5 = 128 + ($input[$i] % 64);
			$utf.= chr($byte1) . chr($byte2) . chr($byte3) . chr($byte4) . chr($byte5);
		}
		if ($input[$i] >= 67108864 && $input[$i] <= 2147483647) {
			$byte1 = 252 + ($input[$i] / 1073741824);
			$byte2 = 128 + (($input[$i] / 16777216) % 64);
			$byte3 = 128 + (($input[$i] / 262144) % 64);
			$byte4 = 128 + (($input[$i] / 4096) % 64);
			$byte5 = 128 + (($input[$i] / 64) % 64);
			$byte6 = 128 + ($input[$i] % 64);
			$utf.= chr($byte1) . chr($byte2) . chr($byte3) . chr($byte4) . chr($byte5) . chr($byte6);
		}
	}
	return $utf;
}
?>